import { Service } from 'egg';
import { Op } from 'sequelize';
import { Result } from '../util/result';
import MsgEnum from '../util/msgEnum';
import { v4 as uuidv4 } from 'uuid';


/**
 * Test Service
 */
export default class User extends Service {
  /**
   * 查找数据库中是否有某用户
   * @param account 用户登录账号
   * @param password 用户登录密码
   */
  public async findUser(account: string, password: string) {
    return await this.ctx.model.User.findOne({
      where: { tel: account, password },
    });
  }

  public async deleteUsers(id) {
    let transaction;
    try {
      transaction = await this.ctx.model.transaction();
      await transaction.commit();
      this.ctx.model.User.destroy({ where: { id } });
      return new Result({ delete: true });
    } catch (e) {
      await transaction.rollback();
      return new Result(null, MsgEnum.SERVER_ERROR);
    }
  }

  public async findUserById(id: string) {
    const res = await this.ctx.model.User.findOne({
      where: { id },
      include: [{ model: this.ctx.model.Position }, { model: this.ctx.model.Title }],
      attributes: { exclude: ['state', 'uuid', 'password', 'fk_organization'] },
    });
    return new Result(res);
  }

  async changUserInfo(
    id: string,
    education: string,
    name: string,
    post: string,
    address: string,
    sex: number,
    major: string,
    department: string
  ) {
    let transaction;
    try {
      transaction = await this.ctx.model.transaction();
      const postuuid = await this.ctx.model.Position.findOne({
        where: { name: post },
      });

      await this.ctx.model.User.update(
        { education, name, post: postuuid.uuid, address, sex, major, department },
        { transaction, where: { id } }
      );

      await transaction.commit();
      return new Result({ upload: true });
    } catch (e) {
      await transaction.rollback();
      return new Result(null, MsgEnum.SERVER_ERROR);
    }
  }


  public async getUserList(
    page: number,
    phone: string,
    email: string,
    name: string,
    role,
    states
  ) {
    let transaction;
    try {

      transaction = await this.ctx.model.transaction();
      const where = {
        name: { [Op.like]: `%${name}%` },
        tel: { [Op.like]: `%${phone}%` },
        email: { [Op.like]: `%${email}%` },
        identity: role == 'all' ? [0, 1] : role,
        state: states == 'all' ? [0, 1, 2, 3] : states,
      };

      const results = await this.ctx.model.User.findAndCountAll({
        where,
        transaction,
        include: [
          {
            model: this.ctx.model.Title,

          },
          {
            model: this.ctx.model.Position,

          },
        ],
        offset: Number((page - 1) * 10),
        limit: 10,
      });
      await transaction.commit();
      return new Result({
        rows: results.rows,
        count: results.count,
      });
    } catch (e) {
      console.log(e);
      await transaction.rollback();
      return new Result(null, MsgEnum.SERVER_ERROR);
    }
  }

  async freezeUser(id, cold) {
    let transaction;
    try {
      transaction = await this.ctx.model.transaction();
      await this.ctx.model.User.update(
        {
          state: cold ? '冻结中' : '正常',
        },
        { transaction, where: { id } }
      );
      await transaction.commit();
      return new Result({ freeze: true }, MsgEnum.FREEZE_SUCCESS);
    } catch (e) {
      console.log(e);
      await transaction.rollback();
      return new Result(null, MsgEnum.SERVER_ERROR);
    }
  }

  async uploadUser(
    id: string,
    education: string,
    name: string,
    post: string,
    address: string,
    sex: number,
    major: string,
    department: string,
    password: string,
    tel: string,
    email: string,
    age: any,
    identity: any,
    state: any,
    role,
    post_uuid,
    role_uuid
  ) {
    let transaction;
    try {
      transaction = await this.ctx.model.transaction();
      await this.ctx.model.Title.update({
        name: role
      },
      {
        transaction,
        where: {
          uuid: role_uuid
        }
      }
      );
      await this.ctx.model.Position.update({
        name: post
      }, {
        transaction,
        where: {
          uuid: post_uuid
        }
      }
      );


      await this.ctx.model.User.update(
        { education, name, address, sex, major, department, password, tel, email, age, identity, state },
        { transaction, where: { id } }
      );
      await transaction.commit();
      return new Result({ upload: true });
    } catch (e) {
      await transaction.rollback();
      return new Result(null, MsgEnum.SERVER_ERROR);
    }
  }

  async deleteUser(id, state) {
    let transaction;
    try {
      transaction = await this.ctx.model.transaction();
      console.log(state);

      if (state == 1) {
        await this.ctx.model.User.destroy({ where: { id }, transaction });
      } else if (state == 2) {
        await this.ctx.model.User.update({ state: 1 }, { where: { id }, transaction });

      } else {
        await this.ctx.model.User.update({ state: 2 }, { where: { id }, transaction });

      }
      await transaction.commit();

      return new Result({ upload: true });

    } catch (e) {
      console.log(e);
      await transaction.rollback();
      return new Result(null, MsgEnum.SERVER_ERROR);
    }
  }


  async crateUser(
    education: string,
    name: string,
    post: string,
    address,
    sex: number,
    major: string,
    department: string,
    password: string,
    tel: string,
    email: string,
    age: any,
    identity: any,
    state: any,
    role,
  ) {
    let transaction;
    try {
      transaction = await this.ctx.model.transaction();
      await this.ctx.model.User.create(
        {
          education,
          name,
          address: address.join(';'),
          sex,
          major,
          department,
          password,
          tel,
          email,
          age,
          identity,
          state,
          role,
          post,
          uuid: uuidv4(),
        },
        { transaction }
      );
      await transaction.commit();
      return new Result({ code: 0 }, MsgEnum.REGISTER_SUCCESS);
    } catch (e) {
      console.log(e);
      await transaction.rollback();
      return new Result(null, MsgEnum.REGISTER_FAILED);
    }
  }
}
